#pragma once

#include <string>

#include <boost/any.hpp>
#include <boost/multi_array.hpp>
#include <boost/shared_ptr.hpp>

typedef std::wstring String;
class Variant
{
public:
	Variant();
	Variant(int v);
	Variant(short v);
	Variant(double v);
	Variant(unsigned char v);
	Variant(String v);
	Variant(const wchar_t* v);
	operator double();
	operator String();
    //Variant& operator+=(T v) {value+=v; return *this;}
    //Variant& operator-=(T v) {value-=v; return *this;}
    //Variant& operator*=(T v) {value*=value; return *this;}
    //Variant& operator/=(T v) {value/=value; return *this;}
    //Variant& operator%=(T v) {value%=value; return *this;}
    //Variant& operator++() {++value; return *this;}
    //Variant& operator--() {--value; return *this;}
    //Variant operator++(int) {return Variant(value++);}
    //Variant operator--(int) {return Variant(value--);}
    //Variant& operator&=(T v) {value&=v; return *this;}
    //Variant& operator|=(T v) {value|=v; return *this;}
    //Variant& operator^=(T v) {value^=v; return *this;}
    //Variant& operator<<=(T v) {value<<=v; return *this;}
    //Variant& operator>>=(T v) {value>>=v; return *this;}
    ////accessors
    //Variant operator+() const {return Variant(+value);}
    //Variant operator!() const {return Variant(!value);}
    //Variant operator~() const {return Variant(~value);}

	bool isEmpty();
	void setEmpty();

	boost::any value;
private:
	int type;
};
#define Empty Variant();

/*
template<class T>
class intWrapperImpl {
    T value;
public:
    typedef T value_type;
    intWrapperImpl() :value() {}
	intWrapperImpl(T v) :value(v) {}
    operator T() const {return value;}
	operator Variant() const {return Variant((value_type)value);}
    //modifiers
    intWrapperImpl& operator=(T v) {value=v; return *this;}
    intWrapperImpl& operator+=(T v) {value+=v; return *this;}
    intWrapperImpl& operator-=(T v) {value-=v; return *this;}
    intWrapperImpl& operator*=(T v) {value*=value; return *this;}
    intWrapperImpl& operator/=(T v) {value/=value; return *this;}
    intWrapperImpl& operator%=(T v) {value%=value; return *this;}
    intWrapperImpl& operator++() {++value; return *this;}
    intWrapperImpl& operator--() {--value; return *this;}
    intWrapperImpl operator++(int) {return intWrapperImpl(value++);}
    intWrapperImpl operator--(int) {return intWrapperImpl(value--);}
    intWrapperImpl& operator&=(T v) {value&=v; return *this;}
    intWrapperImpl& operator|=(T v) {value|=v; return *this;}
    intWrapperImpl& operator^=(T v) {value^=v; return *this;}
    intWrapperImpl& operator<<=(T v) {value<<=v; return *this;}
    intWrapperImpl& operator>>=(T v) {value>>=v; return *this;}
    //accessors
    intWrapperImpl operator+() const {return intWrapperImpl(+value);}
    intWrapperImpl operator-() const {return intWrapperImpl(-value);}
    intWrapperImpl operator!() const {return intWrapperImpl(!value);}
    intWrapperImpl operator~() const {return intWrapperImpl(~value);}
    //friends
	/*
    friend intWrapperImpl operator+(intWrapperImpl iw, intWrapperImpl v) {return iw+=v;}
    friend intWrapperImpl operator+(intWrapperImpl iw, T v) {return iw+=v;}
    friend intWrapperImpl operator+(T v, intWrapperImpl iw) {return intWrapperImpl(v)+=iw;}
    friend intWrapperImpl operator-(intWrapperImpl iw, intWrapperImpl v) {return iw-=v;}
    friend intWrapperImpl operator-(intWrapperImpl iw, T v) {return iw-=v;}
    friend intWrapperImpl operator-(T v, intWrapperImpl iw) {return intWrapperImpl(v)-=iw;}
    friend intWrapperImpl operator*(intWrapperImpl iw, intWrapperImpl v) {return iw*=v;}
    friend intWrapperImpl operator*(intWrapperImpl iw, T v) {return iw*=v;}
    friend intWrapperImpl operator*(T v, intWrapperImpl iw) {return intWrapperImpl(v)*=iw;}
    friend intWrapperImpl operator/(intWrapperImpl iw, intWrapperImpl v) {return iw/=v;}
    friend intWrapperImpl operator/(intWrapperImpl iw, T v) {return iw/=v;}
    friend intWrapperImpl operator/(T v, intWrapperImpl iw) {return intWrapperImpl(v)/=iw;}
    friend intWrapperImpl operator%(intWrapperImpl iw, intWrapperImpl v) {return iw%=v;}
    friend intWrapperImpl operator%(intWrapperImpl iw, T v) {return iw%=v;}
    friend intWrapperImpl operator%(T v, intWrapperImpl iw) {return intWrapperImpl(v)%=iw;}
    friend intWrapperImpl operator&(intWrapperImpl iw, intWrapperImpl v) {return iw&=v;}
    friend intWrapperImpl operator&(intWrapperImpl iw, T v) {return iw&=v;}
    friend intWrapperImpl operator&(T v, intWrapperImpl iw) {return intWrapperImpl(v)&=iw;}
    friend intWrapperImpl operator|(intWrapperImpl iw, intWrapperImpl v) {return iw|=v;}
    friend intWrapperImpl operator|(intWrapperImpl iw, T v) {return iw|=v;}
    friend intWrapperImpl operator|(T v, intWrapperImpl iw) {return intWrapperImpl(v)|=iw;}
    friend intWrapperImpl operator^(intWrapperImpl iw, intWrapperImpl v) {return iw^=v;}
    friend intWrapperImpl operator^(intWrapperImpl iw, T v) {return iw^=v;}
    friend intWrapperImpl operator^(T v, intWrapperImpl iw) {return intWrapperImpl(v)^=iw;}
    friend intWrapperImpl operator<<(intWrapperImpl iw, intWrapperImpl v) {return iw<<=v;}
    friend intWrapperImpl operator<<(intWrapperImpl iw, T v) {return iw<<=v;}
    friend intWrapperImpl operator<<(T v, intWrapperImpl iw) {return intWrapperImpl(v)<<=iw;}
    friend intWrapperImpl operator>>(intWrapperImpl iw, intWrapperImpl v) {return iw>>=v;}
    friend intWrapperImpl operator>>(intWrapperImpl iw, T v) {return iw>>=v;}
    friend intWrapperImpl operator>>(T v, intWrapperImpl iw) {return intWrapperImpl(v)>>=iw;}
	*
	std::wstring toString(){
		return std::to_wstring((long double)v);
	}
};

typedef intWrapperImpl<int> Long;
typedef intWrapperImpl<short> Integer;
typedef intWrapperImpl<unsigned char> Byte;
typedef intWrapperImpl<double> Double;
typedef intWrapperImpl<float> Single;
*/

typedef int Long;
typedef short Integer;
typedef unsigned char Byte;
typedef double Double;
typedef float Single;
typedef bool Boolean;
#define True true
#define False false

//global operators
//strings

	/*
class String {
public:
	String(){};
	String(const wchar_t* v){s=(v);}
	explicit String(const std::wstring& v){s=(v);}
	String(double v){s=(std::to_wstring((long long)v));}

	String(const String &obj){
		s=obj.s;
	}

	String& append(String& s){
		this->s.append(s.s);
		return *this;
	}
	
	String& append(int& v){
		s.append(std::to_wstring((long long)v));
		return *this;
	}

	String& append(double& v){
		s.append(std::to_wstring((long double)v));
		return *this;
	}

	double toFloat() const{
		try {												
			return std::stod(s);	
		}catch (std::invalid_argument ex){												
			throw runtimeException(runtimeException::fbTypeMismatch);												
		}	
	}
#define INT_TO_STRING_ASSIGN(type)						\
	String& operator=(type& rhs)						\
	{													\
		s.assign(std::to_wstring((long double)rhs));	\
		return *this;									\
	}
	INT_TO_STRING_ASSIGN(Long)
	INT_TO_STRING_ASSIGN(Integer)
	INT_TO_STRING_ASSIGN(Byte)
	INT_TO_STRING_ASSIGN(Single)
	INT_TO_STRING_ASSIGN(Double)

	operator double(){
		return toFloat();
	}
	std::wstring s;
};

class Boolean{
public:
	Boolean():value(false){}
	Boolean(int v){value=(v==0)?false:true;}
	Boolean& operator=(int rhs)
	{
		value=(rhs==0)?false:true;
		return *this;
	}
	operator int(){
		return value==false?0:-1;
	}
	bool operator==(Boolean rhs)
	{
		return value==rhs.value;
	}
	bool value;
};

#define True Boolean(true)
#define False Boolean(false)
*/